import {
  Injectable,
  NotFoundException,
  BadRequestException,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Book, BookComment } from './book.entity';
import {
  CreateBookDto,
  UpdateBookDto,
  CreateBookCommentDto,
} from './dto/create-book.dto';
import { UserBook } from './entities/user-book.entity'; // 新增导入
import { HttpException, HttpStatus } from '@nestjs/common'; // 导入缺失的模块

@Injectable()
export class BookService {
  constructor(
    @InjectRepository(Book)
    private bookRepository: Repository<Book>,
    @InjectRepository(BookComment)
    private bookCommentRepository: Repository<BookComment>,
    @InjectRepository(UserBook)
    private userBookRepository: Repository<UserBook>, // 新增UserBook存储库
  ) {}

  async create(createBookDto: CreateBookDto, ownerId: number): Promise<Book> {
    const book = this.bookRepository.create({
      ...createBookDto,
      ownerId,
      status: 'available',
    });
    return this.bookRepository.save(book);
  }

  async findAll(query: any): Promise<[Book[], number]> {
    const { page = 1, limit = 10, category, status, keyword } = query;
    const skip = (page - 1) * limit;

    const qb = this.bookRepository
      .createQueryBuilder('book')
      .leftJoinAndSelect('book.owner', 'owner')
      .leftJoinAndSelect('book.currentBorrower', 'currentBorrower');

    if (category) {
      qb.andWhere('book.category = :category', { category });
    }

    if (status) {
      qb.andWhere('book.status = :status', { status });
    }

    if (keyword) {
      qb.andWhere(
        '(book.title LIKE :keyword OR book.author LIKE :keyword OR book.isbn LIKE :keyword)',
        { keyword: `%${keyword}%` },
      );
    }

    return qb
      .skip(skip)
      .take(limit)
      .orderBy('book.createdAt', 'DESC')
      .getManyAndCount();
  }

  async findOne(id: number): Promise<Book> {
    const book = await this.bookRepository.findOne({
      where: { id },
      relations: ['owner', 'currentBorrower', 'comments', 'comments.user'],
    });

    if (!book) {
      throw new NotFoundException('图书不存在');
    }

    return book;
  }

  async update(
    id: number,
    updateBookDto: UpdateBookDto,
    userId: number,
  ): Promise<Book> {
    const book = await this.findOne(id);

    if (book.ownerId !== userId) {
      throw new BadRequestException('您没有权限修改此图书');
    }

    Object.assign(book, updateBookDto);
    return this.bookRepository.save(book);
  }

  async remove(id: number, userId: number): Promise<void> {
    const book = await this.findOne(id);

    if (book.ownerId !== userId) {
      throw new BadRequestException('您没有权限删除此图书');
    }

    await this.bookRepository.remove(book);
  }

  async borrow(id: number, userId: number): Promise<Book> {
    const book = await this.findOne(id);

    if (book.status !== 'available') {
      throw new BadRequestException('该图书当前不可借阅');
    }

    if (book.ownerId === userId) {
      throw new BadRequestException('不能借阅自己发布的图书');
    }

    book.status = 'borrowed';
    book.currentBorrowerId = userId;
    book.returnDate = new Date(Date.now() + 30 * 24 * 60 * 60 * 1000); // 30天后归还

    return this.bookRepository.save(book);
  }

  // 新增：预约图书
  async reserve(id: number, userId: number): Promise<Book> {
    const book = await this.findOne(id);

    // 检查图书状态是否可预约
    if (book.status !== 'borrowed') {
      throw new BadRequestException('该图书当前不可预约');
    }

    // 检查是否为自己的图书
    if (book.ownerId === userId) {
      throw new BadRequestException('不能预约自己发布的图书');
    }

    // 更新预约状态和信息（假设 Book 实体已包含 currentReserverId 和 reserveDate 字段）
    book.status = 'reserved';
    book.reservedId = userId;

    return this.bookRepository.save(book);
  }

  async return(id: number, userId: number): Promise<Book> {
    const book = await this.findOne(id);

    if (book.status !== 'borrowed' || book.currentBorrowerId !== userId) {
      throw new BadRequestException('您没有借阅此图书');
    }

    book.status = 'available';
    book.currentBorrowerId = null;
    book.returnDate = null;

    return this.bookRepository.save(book);
  }

  async createComment(
    id: number,
    createCommentDto: CreateBookCommentDto,
    userId: number,
  ): Promise<BookComment> {
    const book = await this.findOne(id);

    const comment = this.bookCommentRepository.create({
      ...createCommentDto,
      bookId: id,
      userId,
    });

    return this.bookCommentRepository.save(comment);
  }

  async getMyPublishedBooks(userId: number): Promise<Book[]> {
    return this.bookRepository.find({
      where: { ownerId: userId },
      relations: ['currentBorrower'],
      order: { createdAt: 'DESC' },
    });
  }

  async getMyBorrowedBooks(userId: number): Promise<Book[]> {
    return this.bookRepository.find({
      where: { currentBorrowerId: userId },
      relations: ['owner'],
      order: { createdAt: 'DESC' },
    });
  }

  // 添加收藏
  async addFavorite(userId: number, bookId: number) {
    // 检查是否已收藏
    const existing = await this.userBookRepository.findOne({
      where: { userId, bookId }
    });
    if (existing) {
throw new HttpException('已收藏该图书', HttpStatus.BAD_REQUEST);
    }
    // 创建新收藏记录
    const favorite = this.userBookRepository.create({ userId, bookId });
    await this.userBookRepository.save(favorite);
  }

  // 取消收藏
  async removeFavorite(userId: number, bookId: number) {
    const result = await this.userBookRepository.delete({ userId, bookId });
    if (result.affected === 0) {
      throw new HttpException('未收藏该图书', HttpStatus.NOT_FOUND);
    }
  }

  // 新增：检查用户是否已收藏图书
  async isBookFavorited(userId: number, bookId: number): Promise<boolean> {
    const existing = await this.userBookRepository.findOne({
      where: { userId, bookId }
    });
    return !!existing; // 存在返回true，否则返回false
  }
}
